//============================================================================
// Name        : abstract_factory.cpp
// Author      : Tony Meng
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <memory>

// Abstract product
class Button
{
public:
    virtual ~Button() {}
    virtual void paint() const = 0;
};

// Products
class WinButton : public Button
{
    void paint() const
    {
        std::cout << "WinButton::paint() const" << std::endl;
    }
};

class OsxButton : public Button
{
    void paint() const
    {
        std::cout << "OsxButton::paint() const" << std::endl;
    }
};

// Abstract factory
class GuiFactory
{
public:
    virtual ~GuiFactory() {}
    virtual Button* createButton() const = 0;
};

// Concrete factorys
class WinGuiFactory : public GuiFactory
{
    Button* createButton() const
    {
        return new WinButton();
    }
};


class OsxGuiFactory : public GuiFactory
{
    Button* createButton() const
    {
        return new OsxButton();
    }
};


// Client
class Application
{
public:
    Application(const GuiFactory& factory)
    {
        std::auto_ptr<Button> button(factory.createButton());
        button->paint();
    }
};

int main()
{
    WinGuiFactory winGuiFactory;
    OsxGuiFactory osxGuiFactory;

    Application winApp(winGuiFactory);
    Application osxApp(osxGuiFactory);
}
